package model;

import java.util.Enumeration;
import java.util.HashMap;

import javax.jms.JMSException;
import javax.jms.Message;

import org.apache.qpid.client.message.JMSTextMessage;

/**
 * Subscriber of a Qpid broker.
 * It subscribes to all topics in the broker and provides information about
 * which tags are used the most.
 */
public class TagClouder extends Reader {
    /**
     * Names of the newspapers who have published messages mapped to how many
     * messages they have published.
     */
    private HashMap<String, Integer> newspaperCloud;
//    private HashMap<String, Integer> topicCloud;
    /**
     * Names of the routing keys that have been published to mapped to how many
     * messages have been published to them.
     */
    private HashMap<String, Integer> routingKeyCloud;
//    private HashMap<String, HashMap<String, Integer>> propertyCloud;
    /**
     * Names of the routing keys that have been published to mapped to (the
     * names of the properties that have been used in that topic mapped to
     * (the values of those properties mapped to how many times a property has
     * had that value)).
     */
    private HashMap<String, HashMap<String,
                                    HashMap<String, Integer>>> propertiesCloud;

    //getter
    public HashMap<String, HashMap<String, HashMap<String, Integer>>>
            getPropertiesCloud() {
        return propertiesCloud;
    }

    /**
     * Constructor.
     *
     * @param name  name of the subscriber
     * @param username  username to use to connect to the broker
     * @param password  password to use to connect to the broker
     */
    public TagClouder(final String name, final String username,
                      final String password) {
        super(name, username, password);
        //subscribe to all topics
        addSubscription("*.*", "");
        //initialize the clouds
        newspaperCloud = new HashMap<String, Integer>();
//        topicCloud = new HashMap<String, Integer>();
        routingKeyCloud = new HashMap<String, Integer>();
//        propertyCloud = new HashMap<String, HashMap<String, Integer>>();
        propertiesCloud = new HashMap<String, HashMap<String,
                HashMap<String, Integer>>>();
    }

//    /**
//     * Creates a new tag clouder.
//     *
//     * @param args  array of arguments from the command line (unused)
//     */
//    public static void main(String args []) {
//        new TagClouder("TagClouder", "guest", "guest");
//    }

//    /**
//     * Invoked when a message is asynchronously received.
//     *
//     * @param msg  received message
//     */
//    @Override
//    @SuppressWarnings("unchecked")
//    public void onMessage(final Message msg) {
//        try {
//            String destination = msg.getJMSDestination().toString();
//
//            //if it is a message from the supercontroller
//            if (destination.contains("brokerUpdates")) {
//                super.onMessage(msg);
//            } else { //if it is a message from another client
//                try {
//                    //create the message and read its information
//                    JMSTextMessage message = (JMSTextMessage) msg;
//                    //don't put it in pending messages as nobody will read it
//                    //           System.out.println("Received message \""
//                    //           + message.getText() + "\" from " + destination);
//                    //get the routing key of the message
//                    int iniRoutingKey = destination.indexOf("routingkey");
//                    int iniRoutingKeyValue = iniRoutingKey + 12;
//                    int endRoutingKeyValue = destination.indexOf("'",
//                            iniRoutingKeyValue);
//                    String routingKeyValue = destination.substring(
//                            iniRoutingKeyValue,    endRoutingKeyValue);
//                    //get the name of the newspaper and the topics and subtopics
//                    String[] values = routingKeyValue.split("\\.");
//                    //add 1 to the number of times a newspaper has published
//                    if (newspaperCloud.containsKey(values[0])) {
//                        int timesN = newspaperCloud.get(values[0]);
//                        timesN++;
//                        newspaperCloud.put(values[0], timesN);
//                    } else { //it's the first time that newspaper publishes
//                        newspaperCloud.put(values[0], 1);
//                    }
//                    //           System.out.println(newspaperCloud); //TODO: delete
//                    //           //add 1 to the number of times each topic or subtopic has been published to
//                    //           for(int i = 1; i < values.length; i++) {
//                    //               if (topicCloud.containsKey(values[i])) {
//                    //                   int timesT = topicCloud.get(values[i]);
//                    //                   timesT++;
//                    //                   topicCloud.put(values[i], timesT);
//                    //               } else { //it's the first time that newspaper publishes
//                    //                   topicCloud.put(values[i], 1);
//                    //               }
//                    ////               System.out.println(topicCloud); //TODO: delete
//                    //           }
//
//                    //add 1 to the number of times each routing key has been
//                    //published to
//                    if (routingKeyCloud.containsKey(routingKeyValue)) {
//                        int timesRK = routingKeyCloud.get(routingKeyValue);
//                        timesRK++;
//                        routingKeyCloud.put(routingKeyValue, timesRK);
//                    } else { //it's the first time that routing key is
//                             //published to
//                        routingKeyCloud.put(routingKeyValue, 1);
//                    }
//
//                    //           //add 1 to the number of times the value of a property has been used
//                    //           Enumeration<String> propertyNames = message.getPropertyNames();
//                    //           while(propertyNames.hasMoreElements()) {
//                    //               String propertyName = propertyNames.nextElement();
//                    //               if (!propertyName.equals("header")) {
//                    //                   String propertyValue = message.getStringProperty(propertyName);
//                    //                   if (propertyCloud.containsKey(propertyName)) {
//                    //                       HashMap<String, Integer> tagValues = propertyCloud
//                    //                       .get(propertyName);
//                    //                       if (tagValues.containsKey(propertyValue)) {
//                    //                           int timesV = tagValues.get(propertyValue);
//                    //                           timesV++;
//                    //                           tagValues.put(propertyValue, timesV);
//                    //                       } else { //it's the first time that value is used
//                    //                           tagValues.put(propertyValue, 1);
//                    //                       }
//                    //                   } else { //it's the first time that property is used
//                    //                       HashMap<String, Integer> tagValues = new HashMap<String, Integer>();
//                    //                       tagValues.put(propertyValue, 1);
//                    //                       propertyCloud.put(propertyName, tagValues);
//                    //                   }
//                    //                //               System.out.println(propertyCloud); //TODO: delete
//                    //               }
//                    //           }
//
//                    //add 1 to the number of times the value of a property
//                    //has been used in a topic
//                    if (propertiesCloud.containsKey(routingKeyValue)) {
//                        HashMap<String, HashMap<String, Integer>> tagNames
//                                = propertiesCloud.get(routingKeyValue);
//                        Enumeration<String> propertyNames
//                                = message.getPropertyNames();
//                        //for each property
//                        while (propertyNames.hasMoreElements()) {
//                            String propertyName = propertyNames.nextElement();
//                            if (!propertyName.equals("header")) {
//                                String propertyValue = message
//                                        .getStringProperty(propertyName);
//                                if (tagNames.containsKey(propertyName)) {
//                                    HashMap<String, Integer> tagValues
//                                            = tagNames.get(propertyName);
//                                    if (tagValues.containsKey(propertyValue)) {
//                                        int timesPV
//                                                = tagValues.get(propertyValue);
//                                        timesPV++;
//                                        tagValues.put(propertyValue, timesPV);
//                                        tagNames.put(propertyName, tagValues);
//                                        propertiesCloud.put(
//                                                routingKeyValue, tagNames);
//                                    } else {
//                                        tagValues.put(propertyValue, 1);
//                                        tagNames.put(propertyName, tagValues);
//                                        propertiesCloud.put(
//                                                routingKeyValue, tagNames);
//                                    }
//                                } else {
//                                    HashMap<String, Integer> tagValues
//                                            = new HashMap<String, Integer>();
//                                    tagValues.put(propertyValue, 1);
//                                    tagNames.put(propertyName, tagValues);
//                                    propertiesCloud.put(
//                                            routingKeyValue, tagNames);
//                                }
//                            }
//                        }
//                    //if it's the first time that routing key is published to
//                    } else {
//                        HashMap<String, HashMap<String, Integer>> tagNames
//                                = new HashMap<String,
//                                              HashMap<String, Integer>>();
//                        Enumeration<String> propertyNames
//                                = message.getPropertyNames();
//                        //for each property
//                        while (propertyNames.hasMoreElements()) {
//                            String propertyName = propertyNames.nextElement();
//                            if (!propertyName.equals("header")) {
//                                String propertyValue = message
//                                        .getStringProperty(propertyName);
//                                //it's the first time all properties are used
//                                HashMap<String, Integer> tagValues
//                                        = new HashMap<String, Integer>();
//                                tagValues.put(propertyValue, 1);
//                                tagNames.put(propertyName, tagValues);
//                            }
//                        }
//                        propertiesCloud.put(routingKeyValue, tagNames);
//                    }
//                    //           System.out.println(propertiesCloud);
//
//                } catch (JMSException e) {
//                    System.err.println("Error receiving message.");
//                }
//            }
//        } catch (JMSException e) {
//            e.printStackTrace();
//        }
//   }

}
